import Vue from 'vue';
import { getEntityUuid, isSubDeptType,getSelectKey } from '@/utils/utils';
import { MUTATION_ADD_ENTITY, MUTATION_INIT_PARAMS, MUTATION_REMOVE_ENTITY } from '../mutationTypes.js';
import { ACTION_ADD_ENTITY, ACTION_INIT_PARAMS, ACTION_REMOVE_ENTITY, ACTION_TOGGLE_ENTITY } from '../actionTypes';

/**
 * store
 * @type {{selectedList: *[], selectedEntityMap: {}, selectedUUIDMap: {}, selectParams: {}}}
 */
const selectData = {
	/**
	 * 选人界面右侧区域数据列表。
	 * 列表全部存储实体对象。
	 */
	selectedList: [],
	/**
	 * 选人界面数据k-v映射
	 * k: 实体差别唯一标示(entityUuid)。如人员为`Member|id|deptId|postId`
	 * v:为实体对象
	 */
	selectedEntityMap: {},
	/**
	 * 选人数据实体k-v映射
	 * k:为实体对象，如人员为`Member|id`
	 * v: 实体差别唯一标示(entityUuid，与`selectedMap`的k保持一致)，如人员为`Member|id|deptId|postId`
	 */
	selectedUUIDMap: {},
	/**
	 * 选人界面全局业务参数对象，用于存放各种对外暴力的api参数
	 */
	selectParams: {}
};


/**
 * getters
 * @type {{excludeElementsBeyondMemberSize: ((function(*): ({}))|*), isSingle: (function(*): boolean)}}
 */
let selectDataGetters = {
	/**
	 * 是否为数据单选
	 * @param state
	 * @returns {boolean}
	 */
	isSingle: ({ selectParams }) => {
		return Number(selectParams.maxSize) === 1;
	},
	/**
	 * 获取某个类型超过多少数据，不能选择的业务参数
	 * @param selectParams
	 * @returns {{}}
	 */
	excludeElementsBeyondMemberSize: ({ selectParams }) => {
		const res = {};
		const data = selectParams.excludeElementsBeyondMemberSize;
		if (!data) {
			return res;
		}
		const list = Array.isArray(data) ? data : data.split(',');
		list.forEach((it) => {
			const [type, size] = it.split('|');
			res[type] = Number(size) || 0;
		});
		return res;
	},
	/**
	 * 获取右侧选择的数据
	 * @param state
	 * @returns {[]|*[]|*}
	 */
	selectedList: ({ selectedList }) => {
		return selectedList;
	}
};

/**
 * mutations
 * @type {{}}
 */
let mutations = {
	/**
	 * 初始化选人参数
	 * @param state
	 * @param selectParams 选人配置参数
	 */
	[MUTATION_INIT_PARAMS](state, selectParams) {
		const { checkConfigEnums, excludeElementsBeyondMemberSize } = selectParams;
		/**
		 * checkConfigEnums格式
		 * [{
		 *  checkEmptyMember: true,
		 *  checkLevelScope: true,
		 *  checkMemberSize: false,
		 *  checkWorkScope: true'
		 *  name: "Account"
		 * }]
		 * 将枚举处理为Map
		 */
		const checkConfigMap = {};
		checkConfigEnums.forEach(item => {
			checkConfigMap[item.name] = item;
		});
		selectParams.checkConfigMap = checkConfigMap;

		/**
		 * 将excludeElementsBeyondMemberSize处理为Map
		 * excludeElementsBeyondMemberSize ： Department|3000,Post|3000,Team|3000,Level|3000
		 */
		const excludeBeyondMemberSizeMap = {};
		if (excludeElementsBeyondMemberSize !== '') {
			let items = excludeElementsBeyondMemberSize.split(',');
			items.forEach(item => {
				let typeAndSize = item.split('|');
				if (typeAndSize.length !== 2) {
					console.warn('bad params', excludeElementsBeyondMemberSize, items, item);
					return;
				}
				excludeBeyondMemberSizeMap[typeAndSize[0]] = typeAndSize[1];
			});
		}
		selectParams.excludeBeyondMemberSizeMap = excludeBeyondMemberSizeMap;
		state.selectParams = selectParams;
	},
	/**
	 * 添加数据到已选择区域
	 * @param state
	 * @param payload
	 */
	[MUTATION_ADD_ENTITY](state, payload = { datas: [] }) {
		console.debug('MUTATION_ADD_ENTITY-->payload', payload);
		const { selectedEntityMap, selectedUUIDMap, selectedList, selectParams } = state;
		const { selectType } = selectParams;
		const datas = payload.datas;
		for (let data of datas) {
			let entity = JSON.parse(JSON.stringify(data.entity));
			if (!selectType.includes(entity.type)) {
				// 防止不能被选择的对象，进入store
				console.error(`entity cannot be selected [${entity.type}]!`, entity);
				continue;
			}
			// 取消数据的$_entityUuid
			Vue['delete'](entity, '$_entityUuid');
			let _arguments = data.arguments || { notIncludeSubDept: false };
			let entityKey = entity.type + '|' + entity.id;
			let entityUuid = getEntityUuid(entity, _arguments);
			let selectedKey = getSelectKey(entity);
			if (selectedUUIDMap[entityKey]) {
				// 如果右侧已经存在数据，就不往数据中添加数据
				continue;
			}
			if (isSubDeptType(entity) && _arguments.notIncludeSubDept) {
				// 不包含子部门
				entity.excludeChildDepartment = true;
			}

			Vue.set(selectedEntityMap, entityUuid, entity);
			Vue.set(selectedEntityMap, selectedKey, entity);
			Vue.set(selectedUUIDMap, entityKey, entityUuid);
			selectedList.push(entity);
		}
	},
	/**
	 * 从已选择区域删除数据
	 * @param state
	 * @param entities
	 */
	[MUTATION_REMOVE_ENTITY](state, { entities }) {
		console.debug('MUTATION_REMOVE_ENTITY-->entities', entities);
		let { selectedEntityMap, selectedUUIDMap, selectedList } = state;
		let toDelIds = [];
		for (let entity of entities) {
			let entityKey = entity.type + '|' + entity.id;
			let entityUuid = selectedUUIDMap[entityKey];
			Vue['delete'](selectedUUIDMap, entityKey);
			if (!entityUuid) {
				console.debug(`entity not found[${entityKey}]!`, entity);
				continue;
			}
			Vue['delete'](selectedEntityMap, entityKey);
			Vue['delete'](selectedEntityMap, entityUuid);
			toDelIds.push(entityUuid);
		}
		// 删除list元素
		for (let i = 0; i < selectedList.length;) {
			const entity = selectedList[i];
			if (toDelIds.includes(entity.$_entityUuid)) {
				Vue['delete'](selectedList, i);
			} else {
				i++;
			}
		}
	}
};


/**
 * actions
 */
let actions = {
	/**
	 * 初始化选人参数
	 * @param commit
	 * @param selectParams 选人配置参数
	 */
	[ACTION_INIT_PARAMS]({ commit }, selectParams) {
		console.debug('ACTION_INIT_PARAMS-->selectParams', selectParams);
		commit(MUTATION_INIT_PARAMS, selectParams);
	},
	/**
	 * 【全选】添加数据到已选择区域
	 * @param commit
	 * @param state
	 * @param payload
	 * @returns {Promise<unknown>}
	 */
	async [ACTION_ADD_ENTITY]({ commit, state, getters }, payload = { entities: [], notIncludeSubDept: [] }) {
		return new Promise((resolve) => {
			console.debug('ACTION_ADD_ENTITY-->payload', payload);
			let { entities, notIncludeSubDept } = payload;
			if (!entities && entities.length === 0) {
				resolve();
				return;
			}
			const { selectedUUIDMap, selectedList, selectParams } = state;
			// 如果是单选
			let isSingle = getters.isSingle;
			if (isSingle) {
				let addEntity = entities[entities.length - 1];
				const { selectType } = selectParams;
				if (!selectType.includes(addEntity.type)) {
					// 防止不能被选择的对象，进入store
					console.error(`entity cannot be selected [${addEntity.type}]!`, addEntity);
					return;
				}
				commit(MUTATION_REMOVE_ENTITY, { entities: selectedList });
				commit(MUTATION_ADD_ENTITY, {
					datas: [{
						entity: addEntity,
						arguments: {
							notIncludeSubDept: notIncludeSubDept && notIncludeSubDept.includes(addEntity.id)
						}
					}]
				});
				resolve();
				return;
			}

			// 添加新数据，需要将原来的数据删除
			let toDelEntities = [];
			let addEntities = [];
			let addEntityKeys = [];
			for (let entity of entities) {
				let entityKey = entity.type + '|' + entity.id;
				let uuid = selectedUUIDMap[entityKey];
				if (uuid) {
					toDelEntities.push(entity);
				}
				if (addEntityKeys.includes(entityKey)) {
					// 当前添加的数据已经存在实体
					continue;
				}
				addEntities.push({
					entity,
					arguments: {
						notIncludeSubDept: notIncludeSubDept && notIncludeSubDept.includes(entity.id)
					}
				});
				addEntityKeys.push(entityKey);
			}
			if (toDelEntities.length > 0) {
				commit(MUTATION_REMOVE_ENTITY, { entities: toDelEntities });
			}
			console.debug('ACTION_ADD_ENTITY-->addEntities', addEntities);
			commit(MUTATION_ADD_ENTITY, { datas: addEntities });
			resolve();
		});
	},
	/**
	 * 【清空】从已选择区域删除数据
	 * @param commit
	 * @param entities 需要被删除的实体
	 * @returns {Promise<unknown>}
	 */
	async [ACTION_REMOVE_ENTITY]({ commit }, { entities }) {
		return new Promise((resolve) => {
			console.debug('ACTION_REMOVE_ENTITY-->entities', entities);
			commit(MUTATION_REMOVE_ENTITY, { entities });
			resolve();
		});
	},
	/**
	 * 选择/清空已选区的实体
	 * @param entities 添加/删除实体
	 * @returns {Promise<unknown>}
	 * @param payload
	 */
	async [ACTION_TOGGLE_ENTITY]({ commit, state, getters }, payload = { entities: [], notIncludeSubDept: [] }) {
		return new Promise((resolve) => {
			let { entities, notIncludeSubDept } = payload;
			const { selectedList, selectedEntityMap, selectedUUIDMap, selectParams } = state;
			console.debug('ACTION_TOGGLE_ENTITY===>entities', entities, notIncludeSubDept);
			if (!entities) {
				resolve();
				return;
			}
			// 如果是单选
			let isSingle = getters.isSingle;
			if (isSingle) {
				const { selectType } = selectParams;
				const addEntity = entities[0];
				if (!selectType.includes(addEntity.type)) {
					// 防止不能被选择的对象，进入store
					console.error(`entity cannot be selected [${addEntity.type}]!`, addEntity);
					return;
				}
				commit(MUTATION_REMOVE_ENTITY, { entities: selectedList });
				commit(MUTATION_ADD_ENTITY, {
					datas: [{
						entity: addEntity,
						arguments: {
							notIncludeSubDept: notIncludeSubDept && notIncludeSubDept.includes(addEntity.id)
						}
					}]
				});
				resolve();
				return;
			} 

			// 添加新数据，需要将原来的数据删除
			let toDelEntities = [];
			let addEntities = [];
			for (let entity of entities) {
				let entityKey = entity.type + '|' + entity.id;
				let uuid = selectedUUIDMap[entityKey];
				if (selectedEntityMap[uuid]) {
					toDelEntities.push(entity);
					continue;
				}
				addEntities.push({
					entity,
					arguments: {
						notIncludeSubDept: notIncludeSubDept && notIncludeSubDept.includes(entity.id)
					}
				});
			}
			if (toDelEntities.length) {
				commit(MUTATION_REMOVE_ENTITY, { entities: toDelEntities });
			}
			if (addEntities.length) {
				commit(MUTATION_ADD_ENTITY, { datas: addEntities });
			}
			resolve();
		});
	}
};

export default {
	namespaced: true,
	state: selectData,
	getters: selectDataGetters,
	mutations,
	actions
};
